/***********************************************************************************
Copy right:	    hqyj Tech.
Author:         jiaoyue
Date:           2023.07.01
Description:    http请求处理
***********************************************************************************/

#include <sys/types.h>
#include <sys/socket.h>
#include "custom_handle.h"

#define KB 1024
#define HTML_SIZE (64 * KB)

// 普通的文本回复需要增加html头部
#define HTML_HEAD "Content-Type: text/html\r\n" \
                  "Connection: close\r\n"
struct msgbuf
{
    long mtype;
    int num1;
    int num2; 
};
static int handle_login(int sock, const char *input)
{
    char reply_buf[HTML_SIZE] = {0};
    char *uname = strstr(input, "username=");
    uname += strlen("username=");
    char *p = strstr(input, "password");
    *(p - 1) = '\0';
    printf("username = %s\n", uname);

    char *passwd = p + strlen("password=");
    printf("passwd = %s\n", passwd);

    if (strcmp(uname, "admin") == 0 && strcmp(passwd, "admin") == 0)
    {
        sprintf(reply_buf, "<script>localStorage.setItem('usr_user_name', '%s');</script>", uname);
        strcat(reply_buf, "<script>window.location.href = '/index.html';</script>");
        send(sock, reply_buf, strlen(reply_buf), 0);
    }
    else
    {
        printf("web login failed\n");

        //"用户名或密码错误"提示，chrome浏览器直接输送utf-8字符流乱码，没有找到太好解决方案，先过渡
        char out[128] = {0xd3, 0xc3, 0xbb, 0xa7, 0xc3, 0xfb, 0xbb, 0xf2, 0xc3, 0xdc, 0xc2, 0xeb, 0xb4, 0xed, 0xce, 0xf3};
        sprintf(reply_buf, "<script charset='gb2312'>alert('%s');</script>", out);
        strcat(reply_buf, "<script>window.location.href = '/login.html';</script>");
        send(sock, reply_buf, strlen(reply_buf), 0);
    }

    return 0;
}

static int handle_add(int sock, const char *input)
{
    int number1, number2;

    // input必须是"data1=1data2=6"类似的格式，注意前端过来的字符串会有双引号
    sscanf(input, "\"data1=%ddata2=%d\"", &number1, &number2);
    printf("num1 = %d\n", number1);

    char reply_buf[HTML_SIZE] = {0};
    printf("num = %d\n", number1 + number2);
    sprintf(reply_buf, "%d", number1 + number2);
    printf("resp = %s\n", reply_buf);
    send(sock, reply_buf, strlen(reply_buf), 0);

    return 0;
}
static int handle_contrl(int sock, const char *input)
{
    key_t key1;
    int msgid;
    key1 = ftok("msg.c", 'a');
    if (key1 < 0)
    {
        perror("ftok err1\n");
        return -1;
    }
    msgid = msgget(key1, IPC_CREAT | IPC_EXCL | 0666);
    if (msgid <= 0)
    {
        if (errno == EEXIST)
        {
            msgid = msgget(key1, 0666);
        }
        else
        {
            perror("misgget err\n");
            return -1;
        }
    }
    int num1, num2;
    sscanf(input, "contrl=%d %d ", &num1, &num2);
    printf("num1 = %d\n", num1);
    printf("num2 = %d\n", num2);
    struct msgbuf msg = {1, num1, num2};
    msgsnd(msgid, &msg, sizeof(struct msgbuf) - sizeof(long), 0);
    char str[64] = "send ok";
    send(sock, str, sizeof(str), 0);
    return 0;
}
static int handle_get(int sock, const char *input)
{
    key_t key2;
    int shmid;
    key2 = ftok("shm.c", 'c');
    if (key2 < 0)
    {
        perror("ftok err2\n");
        return -1;
    }
    shmid = shmget(key2, 128, IPC_CREAT | IPC_EXCL | 0777);
    if (shmid <= 0)
    {
        if (errno == EEXIST)
        {
            shmid = shmget(key2, 128, 0777);
        }
        else
        {
            perror("shemget err");
            return -1;
        }
    }
    u_int16_t dest[10] = {};
    char *p = shmat(shmid, NULL, SHM_RDONLY); // 对该共享内存只读
    if (p == (char *)-1)
    {
        perror("shmat err\n");
        return -1;
    }
    // 使用

    // char val_buf[HTML_SIZE] = {0};
    // memcpy(dest, p, sizeof(val_buf));
    // strcpy(val_buf, p);
    send(sock, p, strlen(p), 0);
}
/**
 * @brief 处理自定义请求，在这里添加进程通信
 * @param input
 * @return
 */
int parse_and_process(int sock, const char *query_string, const char *input)
{
    // query_string不一定能用的到

    // 先处理登录操作
    if (strstr(input, "username=") && strstr(input, "password="))
    {
        return handle_login(sock, input);
    }
    // 处理求和请求
    else if (strstr(input, "data1=") && strstr(input, "data2="))
    {
        return handle_add(sock, input);
    }
    else if (strstr(input, "contrl="))
    {
        return handle_contrl(sock, input);
    }
    else if (strstr(input, "modbus"))
    {
        return handle_get(sock, input);
    }

    else // 剩下的都是json请求，这个和协议有关了
    {
        // 构建要回复的JSON数据
        const char *json_response = "{\"message\": \"Hello, client!\"}";

        // 发送HTTP响应给客户端
        send(sock, json_response, strlen(json_response), 0);
    }

    return 0;
}
